package main

import (
	"fmt"
	"github.com/spf13/viper"
)

/*
	把值存进viper
		建立默认值: 一个好的配置系统应该支持默认值。键不需要默认值,但如果没有通过配置文件、环境变量、远程配置或命令行编制设置键,则默认值非常有用
*/

//func main() {
//	//	建立默认值示例
//	viper.SetDefault("fileDir", "./")
//	/*
//		读取配置文件
//	*/
//	//viper.SetConfigName("./config.yaml")  //配置文件名称(有扩展名)
//	viper.SetConfigName("config")         //配置文件名称(无扩展名)
//	viper.SetConfigType("yaml")           //如果配置的名称中灭有扩展名,需要配置此项
//	viper.AddConfigPath("/etc/appname/")  //查找配置文件所在的路径
//	viper.AddConfigPath("$HOME/.appname") //多次调用以添加多个搜索路径
//	viper.AddConfigPath(".")              //还可以在工作目录中查找配置
//	//从上述AddConfigPath中指定的路径依次去查找设定的config.yaml文件并读取该文件
//	err := viper.ReadInConfig()
//	if err != nil {
//		panic(fmt.Errorf("fatal error config file: %s\n", err))
//	}
//
//	//从上述AddConfigPath中指定的路径依次去查找设定的config.yaml文件并读取该文件，当找不到配置文件的特定情况可以做以下配置
//	if err := viper.ReadInConfig(); err != nil {
//		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
//			//	配置文件未找到 的错误
//		} else {
//			//配置文件找到,但产生了另外的错误
//		}
//	}
//	//	配置文件找到并成功解析
//}
//func main() {
//	/*
//		写入配置文件(把程序里面修改的配置写进到配置文件中)
//		WriteConfig: 将当前的viper配置写入预定义的路径并覆盖(如果存在的话)。如果没有预定义路径,则报错
//		SafeWriteConfig: 将当前的viper配置写入预定义的路径。如果没有预定义路径,则报错。如果存在，将不会覆盖当前的配置文件
//		WriteConfigAs: 将当前的viper配置写入给的给定的文件路径.将覆盖给定的文件(如果它存在的话)
//		SafeWriteConfigAs: 将当前的viper配置写入给定的文件路径. 不会覆盖给定的文件(如果它存在的话)
//		根据经验,标记为safe的所有方法都不会 覆盖任何文件,而是直接创建(如果存在)，而默认行为是创建或截断
//	*/
//	viper.WriteConfig() //将当前配置写入到上述定义的AddconfigPath和 SetConfigName中
//	viper.SafeWriteConfig()
//	viper.WriteConfigAs("/path/to/my/.config")
//	viper.SafeWriteConfigAs("/path/to/my/.config")
//
//}

//当我们需要将viper读取的配置反序列到我们定义的结构体变量中时，一定要使用mapstructure tag
type Config struct {
	Host        string `mapstructure:"host"`
	Port        int    `mapstructure:"port"`
	Mysqlconfig `mapstructure:"mysql"`
}
type Mysqlconfig struct {
	Host     string `mapstructure:"host"`
	Password string `mapstructure:"password"`
	Port     int    `mapstructure:"port"`
	Dbname   string `mapstructure:"dbname"`
}

func main() {
	//	建立默认值示例
	viper.SetDefault("fileDir", "./")
	/*
		读取配置文件
	*/
	//viper.SetConfigName("./config.yaml")  //配置文件名称(有扩展名)
	viper.SetConfigName("config")         //配置文件名称(无扩展名)
	viper.SetConfigType("yaml")           //如果配置的名称中灭有扩展名,需要配置此项
	viper.AddConfigPath("/etc/appname/")  //查找配置文件所在的路径
	viper.AddConfigPath("$HOME/.appname") //多次调用以添加多个搜索路径
	viper.AddConfigPath(".")              //还可以在工作目录中查找配置
	//从上述AddConfigPath中指定的路径依次去查找设定的config.yaml文件并读取该文件
	err := viper.ReadInConfig()
	if err != nil {
		panic(fmt.Errorf("fatal error config file: %s\n", err))
	}
	var C Config

	err = viper.Unmarshal(&C) //反序列化读取
	if err != nil {
		fmt.Printf("unable to decode into struct, %v", err)
	}
	fmt.Printf("c:%#v\n", C)
}
